package cc.siyecao.mapper.wrapper;

import cc.siyecao.mapper.conditions.Func;
import cc.siyecao.mapper.enums.SqlFunction;

public abstract class AbstractFuncWrapper<W, R, T> extends EntityWrapper<W, T> implements Func<W, R> {

    @Override
    public W avg(R column) {
        return select( column, funColumn( SqlFunction.AVG, column ) );
    }

    @Override
    public W sum(R column) {
        return select( column, funColumn( SqlFunction.SUM, column ) );
    }

    @Override
    public W max(R column) {
        return select( column, funColumn( SqlFunction.MAX, column ) );
    }

    @Override
    public W min(R column) {
        return select( column, funColumn( SqlFunction.MIN, column ) );
    }

    @Override
    public W lower(R column) {
        return select( column, funColumn( SqlFunction.LOWER, column ) );
    }

    @Override
    public W upper(R column) {
        return select( column, funColumn( SqlFunction.UPPER, column ) );
    }

    @Override
    public W replace(R column, String source, String target) {
        return select( column, funColumn( SqlFunction.REPLACE, column, source, target ) );
    }

    @Override
    public W length(R column) {
        return select( column, funColumn( SqlFunction.LENGTH, column ) );
    }

    @Override
    public W round(R column, Integer value) {
        return select( column, funColumn( SqlFunction.ROUND, column, value ) );
    }

    @Override
    public W trim(R column) {
        return select( column, funColumn( SqlFunction.TRIM, column ) );
    }

    private String funColumn(SqlFunction function, R column) {
        String columnName = columnName( column );
        return function.toFnStr( columnName );
    }

    private String funColumn(SqlFunction function, R column, Integer value) {
        String columnName = columnName( column );
        return function.toFnStr( columnName, value );
    }

    private String funColumn(SqlFunction function, R column, String source, String target) {
        String columnName = columnName( column );
        return function.toFnStr( columnName, source, target );
    }

    private W select(R column, String funColumn) {
        String columnName = columnName( column );
        String fieldName = fieldName( column );
        //fix 如果有设置 autoResultMap 就不能有 AS
        if (columnName.equals( fieldName ) && funColumn.equals( fieldName )) {
            sqlSelect.addString( funColumn );
        } else {
//            Matcher matcher = DELIMITER.matcher( columnName );
//            //eg: mysql `order` == field order | sqlserver [order] == field order
//            if (matcher.find() && fieldName.equals( matcher.group( 1 ) )) {
//                sqlSelect.addString( funColumn );
//            } else {
            sqlSelect.addString( funColumn + " AS " + fieldName );
//            }
        }
        return typedThis;
    }

    /**
     * 获取 columnName
     */
    abstract String columnName(R column);

    /**
     * 获取 fieldName
     */
    abstract String fieldName(R column);

}
